{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# SSL Connection Examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connecting to a Redis instance via SSL."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import redis\n",
    "\n",
    "ssl_connection = redis.Redis(host='localhost', port=6666, ssl=True, ssl_cert_reqs=\"none\")\n",
    "ssl_connection.ping()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connecting to a Redis instance via a URL string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import redis\n",
    "url_connection = redis.from_url(\"redis://localhost:6379?ssl_cert_reqs=none&decode_responses=True&health_check_interval=2\")\n",
    "url_connection.ping()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connecting to a Redis instance via SSL, while specifying a self-signed SSL certificate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "import redis\n",
    "\n",
    "ssl_certfile=\"some-certificate.pem\"\n",
    "ssl_keyfile=\"some-key.pem\"\n",
    "ssl_ca_certs=ssl_certfile\n",
    "\n",
    "ssl_cert_conn = redis.Redis(\n",
    "    host=\"localhost\",\n",
    "    port=6666,\n",
    "    ssl=True,\n",
    "    ssl_certfile=ssl_certfile,\n",
    "    ssl_keyfile=ssl_keyfile,\n",
    "    ssl_cert_reqs=\"required\",\n",
    "    ssl_ca_certs=ssl_ca_certs,\n",
    ")\n",
    "ssl_cert_conn.ping()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connecting to a Redis instance via SSL, and validate the OCSP status of the certificate\n",
    "\n",
    "The redis package is design to be small, meaning extra libraries must be installed, in order to support OCSP stapling. As a result, first install redis via:\n",
    "\n",
    "*pip install redis[ocsp]*\n",
    "\n",
    "This will install cryptography, requests, and PyOpenSSL, none of which are generally required to use Redis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import os\n",
    "import redis\n",
    "\n",
    "ssl_certfile=\"some-certificate.pem\"\n",
    "ssl_keyfile=\"some-key.pem\"\n",
    "ssl_ca_certs=ssl_certfile\n",
    "\n",
    "ssl_cert_conn = redis.Redis(\n",
    "    host=\"localhost\",\n",
    "    port=6666,\n",
    "    ssl=True,\n",
    "    ssl_certfile=ssl_certfile,\n",
    "    ssl_keyfile=ssl_keyfile,\n",
    "    ssl_cert_reqs=\"required\",\n",
    "    ssl_validate_ocsp=True\n",
    ")\n",
    "ssl_cert_conn.ping()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connect via SSL, validate OCSP-stapled certificates\n",
    "\n",
    "The redis package is design to be small, meaning extra libraries must be installed, in order to support OCSP stapling. As a result, first install redis via:\n",
    "\n",
    "*pip install redis[ocsp]*\n",
    "\n",
    "This will install cryptography, requests, and PyOpenSSL, none of which are generally required to use Redis."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using a custom SSL context and validating against an expected certificate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import redis\n",
    "import OpenSSL\n",
    "\n",
    "ssl_certfile=\"some-certificate.pem\"\n",
    "ssl_keyfile=\"some-key.pem\"\n",
    "ssl_ca_certs=ssl_certfile\n",
    "ssl_expected_certificate = \"expected-ocsp-certificate.pem\"\n",
    "\n",
    "# PyOpenSSL is used only for the purpose of validating the ocsp\n",
    "# stapled response\n",
    "ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)\n",
    "ctx.use_certificate_file=ssl_certfile\n",
    "ctx.use_privatekey_file=ssl_keyfile\n",
    "expected_certificate = open(ssl_expected_certificate, 'rb').read()\n",
    "\n",
    "ssl_cert_conn = redis.Redis(\n",
    "    host=\"localhost\",\n",
    "    port=6666,\n",
    "    ssl=True,\n",
    "    ssl_certfile=ssl_certfile,\n",
    "    ssl_keyfile=ssl_keyfile,\n",
    "    ssl_cert_reqs=\"required\",\n",
    "    ssl_ocsp_context=ctx,\n",
    "    ssl_ocsp_expected_cert=expected_certificate,\n",
    ")\n",
    "ssl_cert_conn.ping()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Naive validation of a stapled OCSP certificate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import redis\n",
    "import OpenSSL\n",
    "\n",
    "ssl_certfile=\"some-certificate.pem\"\n",
    "ssl_keyfile=\"some-key.pem\"\n",
    "ssl_ca_certs=ssl_certfile\n",
    "ssl_expected_certificate = \"expected-ocsp-certificate.pem\"\n",
    "\n",
    "# PyOpenSSL is used only for the purpose of validating the ocsp\n",
    "# stapled response\n",
    "ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)\n",
    "ctx.use_certificate_file=ssl_certfile\n",
    "ctx.use_privatekey_file=ssl_keyfile\n",
    "\n",
    "ssl_cert_conn = redis.Redis(\n",
    "    host=\"localhost\",\n",
    "    port=6666,\n",
    "    ssl=True,\n",
    "    ssl_certfile=ssl_certfile,\n",
    "    ssl_keyfile=ssl_keyfile,\n",
    "    ssl_cert_reqs=\"required\",\n",
    "    ssl_validate_ocsp_stapled=True,\n",
    ")\n",
    "ssl_cert_conn.ping()"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "d45c99ba0feda92868abafa8257cbb4709c97f1a0b5dc62bbeebdf89d4fad7fe"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
